﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AddListEventReceiver.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Creates a new SPWeb.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.Saf.Actions.Wss.List
{
    using System;
    using System.Collections.Generic;

    using Entities;
    using Engine;

    using SharePoint.Wss.Attributes;
    using SharePoint.Wss.Lists;

 
    [CollaborisClass(
        Title = "Add List Item Event Receiver",
        ReleaseStatus = ReleaseStatus.Stable,
        DisableDocumentation = false,
        ContactAuthorEmail = "Support@Collaboris.co.uk",
        Summary = "Adds a list event receiver to a SharePoint list.",
        Remarks = "You must deploy the code (that implemented the receiver) prior to running this action.",
        UndoImplemented = true,
        ClassGuid = "{156E17A5-A7BA-4e1f-8A48-1BC341A7C651}"
    )
    ]
    public class AddListItemEventReceiver : WSSActionBase<ListItemEventInfo>
    {

        /// <summary>
        /// If the specified List exists then it will be deleted.
        /// <see cref="WebInfo"/>
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entity">The data entityList.</param>
        /// <returns></returns>
        protected override ProcessStatus DoAction(SafContext context, ListItemEventInfo entity)
        {
            this.Trace.TraceMethodStart("DoAction");

            ProcessStatus rstate = this.ProcessListItemEventInfo(entity, ProcessMode.Do, context);

            this.Trace.TraceMethodEnd("DoAction");
            return rstate;
        }

        /// <summary>
        /// Undoes the action.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        protected override ProcessStatus UndoAction(SafContext context, ListItemEventInfo entity)
        {
            this.Trace.TraceMethodStart("UndoAction");

            ProcessStatus rstate = this.ProcessListItemEventInfo(entity, ProcessMode.Undo, context);

            this.Trace.TraceMethodEnd("UndoAction");
            return rstate;
        }

        /// <summary>
        /// Process the ListItemEventInfo entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private ProcessStatus ProcessListItemEventInfo(ListItemEventInfo entity, ProcessMode mode, SafContext context)
        {
            this.Trace.TraceMethodStart("ProcessListItemEventInfo()");
            ProcessStatus status;

            // Do - adds the event.
            if (mode == ProcessMode.Do)
            {
                status = this.ProcessDo(context, entity);
            }
            else
            {
                // UnDo - removes the event.
                status = this.ProcessUndo(context, entity);
            }

            this.Trace.TraceMethodEnd("ProcessListItemEventInfo()");

            return status;
        }

        /// <summary>
        /// Processes the do.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        private ProcessStatus ProcessDo(SafContext context, ListItemEventInfo entity)
        {
            Guid listtoAddEvent = SPListHelper.GetListGuid(TargetWeb, entity.ListName);

            if (listtoAddEvent == Guid.Empty)
            {
                this.Trace.TraceVerbose("The list {0} doesn't exist in this web {1}", entity.ListName, TargetWeb.Url);

                return ProcessStatus.Invalid;
            }

            this.Trace.TraceVerbose(
                    "Attempting to add event: '{0}' to the List: '{1}'",
                    entity.EventReceiverType.Value.ToString("d"),
                    entity.ListName);

            SPListHelper.AddListItemEvent(
                    TargetWeb,
                    entity.ListName,
                    entity.EventReceiverType.Value,
                    entity.AssemblyName,
                    entity.ClassName);

            this.Trace.TraceVerbose(
                    "Successfully added the event: '{0}' to the List: '{1}'",
                    entity.EventReceiverType.Value.ToString("d"),
                    entity.ListName);

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Processes the un do.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        private ProcessStatus ProcessUndo(SafContext context, ListItemEventInfo entity)
        {
            Guid listtoAddEvent = SPListHelper.GetListGuid(TargetWeb, entity.ListName);

            if (listtoAddEvent == Guid.Empty)
            {
                this.Trace.TraceVerbose(
                        "The list {0} doesn't exist in this web {1}", entity.ListName, TargetWeb.Url);

                return ProcessStatus.Invalid;
            }

            this.Trace.TraceVerbose(
                                "Attempting to remove event: '{0}' from the List: '{1}'", 
                                entity.EventReceiverType.Value.ToString("d"), 
                                entity.ListName);

            SPListHelper.RemoveListItemEvent(
                    TargetWeb,
                    entity.ListName,
                    entity.EventReceiverType.Value,
                    entity.AssemblyName,
                    entity.ClassName);

            this.Trace.TraceVerbose(
                    "Successfully removed the event: '{0}' from the List: '{1}'", 
                    entity.EventReceiverType.Value.ToString("d"), 
                    entity.ListName);

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Checks the Data entity for Validity
        /// </summary>
        /// <param name="context">The <see cref="SafContext"/>context.</param>
        /// <param name="entity">The data entity to Validate</param>
        /// <param name="errors">List of <see cref="ValidationError"/>s</param>
        /// <param name="mode"><see cref="ProcessMode"/> signalling wheter we are Doing, or Undoing the action.</param>
        /// <returns>false if invalid</returns>
        protected override bool IsValid(SafContext context, ListItemEventInfo entity, ref List<ValidationError> errors, ProcessMode mode)
        {
            int currentCount = errors.Count;

            // Validate each object now.
            ValidateStringForNull(entity.ListName, "entity.ListName", ref errors);
            ValidateStringForNull(entity.ClassName, "entity.ClassName", ref errors);
            ValidateStringForNull(entity.AssemblyName, "entity.AssemblyName", ref errors);
            ValidateNullable(entity.EventReceiverType, "entity.EventReceiverType", ref errors);

            // Have we added errors ?
            return errors.Count == currentCount;
        }
    }
}